#ifndef _OPERATION_H
#define _OPERATION_H

namespace NetIO
{
class Reactor_Impl;

struct Operation
{
	friend class Operation_Queue;
	friend class Completed_Queue;
public:
	enum
	{
		OR_OK,
		OR_FAILED,
		OR_CONTINUE,
		OR_CANCLE
	};

	Operation( )
	{
		reset( 0 );
	}

public:
	~Operation( void ) {}

	int optype( )
	{
		return optype_;
	}

	void optype( int optype )
	{
		optype_ = optype;
	}

	int errcode( )
	{
		return errcode_;
	}
	void errcode( int errcode )
	{
		errcode_ = errcode;
	}

	DataBlock* data_block( )
	{
		return data_block_;
	}

	void data_block( DataBlock *data_block )
	{
		data_block_ = data_block;
	}

	void *act( )
	{
		return act_;
	}

	void act( void *act )
	{
		act_ = act;
	}

	int bytes_transferred( )
	{
		return bytes_transferred_;
	}

	void bytes_transferred( int bytes_transferred )
	{
		bytes_transferred_ = bytes_transferred;
	}

	Socket& handle( )
	{
		return handle_;
	}
	void handle( const Socket &h )
	{
		handle_ = h;
	}

	bool perform( );

	void reset( Reactor_Impl *reactor )
	{
		optype_ = OperationType::NONE;
		errcode_ = 0;
		data_block_ = 0;
		act_ = 0;
		bytes_transferred_ = 0;
		port_ = 0;
		TAILQ_NEXT( this, field_ ) = 0;
		reactor_ = reactor;
	}

	void destroy( )
	{
		delete this;
	}

private:

	typedef bool ( Operation::*PERFORM_FUNC )( void );

	static PERFORM_FUNC	op_func_[ OperationType::MAX ];

	bool read( );

	bool write( );

	bool connect( );

	bool accept( );

private:

	int optype_;

	int errcode_;

	DataBlock *data_block_;

	void *act_;

	int bytes_transferred_;

	Socket handle_;

	string ip_;

	short port_;

	Reactor_Impl *reactor_;

private:
	TAILQ_ENTRY( Operation ) field_;
};

};
#endif

